/*
 * T.Raynal - A.Aviles - F.Diallo
 * XML-Scenarios
 * PPA AL5-2
 * December 2012 
 */
package facade;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import common.Context;
import common.exception.*;
import common.interfaces.Callback;
import model.Scenario;
import model.Serializer;
import model.scenario.*;
import model.serialization.*;

// TODO: Auto-generated Javadoc
/**
 * Facade for scenarios handling.
 */
public class ScenarioManager {
	
	
	private List<Scenario> _scenarios = null;
	
	/**
	 * Instantiates a new scenario manager.
	 *
	 * @throws InitialisationException
	 */
	public ScenarioManager() throws InitialisationException
	{
		Context.init();
		_scenarios = new ArrayList<>();
	}
	
	/**
	 * Available scenarios files.
	 *
	 * @return Available scenarios files
	 */
	private File [] availableScenariosFiles()
	{
		return 
				new File(Context.REPOSITORY_SCENARIOS.getAbsolutePath()).listFiles();
	}
	
	/**
	 * Available saves files.
	 *
	 * @return Available saves files
	 */
	private File [] availableSavesFiles()
	{
		return 
				new File(Context.REPOSITORY_SAVES.getAbsolutePath()).listFiles();
	}


	/**
	 * Load available scenarios
	 *
	 * @throws UnregisteredOperatorException
	 * @throws JDOMException
	 * @throws IOException
	 * @throws XmlParsingException
	 */
	public void load() throws UnregisteredOperatorException, JDOMException, IOException, XmlParsingException
	{
		for (File file : availableScenariosFiles()) {
					load(file.getAbsolutePath());
		}
	}
	
	/**
	 * Load a save.
	 *
	 * @param Save file
	 * @return Scenario
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public Scenario loadSave (String fileName) throws IOException, ClassNotFoundException
	{
		FileInputStream fis = new FileInputStream(fileName);
		ObjectInputStream ois= new ObjectInputStream(fis);
		Scenario result = (Scenario) ois.readObject(); 
		ois.close();
		fis.close();
		return result; 
		
	}
	
	/**
	 * Available saves
	 *
	 * @return Saves
	 */
	public List<String> saves()
	{
		List<String> s = new ArrayList<>();
		
		for (File file : availableSavesFiles()) {
			s.add(file.getAbsolutePath());
		}
		
		return s;
	}
	
	/**
	 * Scenarios.
	 *
	 * @return the list
	 */
	public List<Scenario> scenarios()
	{
		return _scenarios;
	}

	/**
	 * Load a specific scenario file.
	 *
	 * @param XML file
	 * @throws JDOMException
	 * @throws IOException
	 * @throws XmlParsingException
	 * @throws UnregisteredOperatorException
	 */
	public void load (String xmlFile) throws JDOMException, IOException, XmlParsingException, UnregisteredOperatorException
	{
		for (Scenario scenario : new ScenarioBuilder(xmlFile).build()) {
			if (!_scenarios.contains(scenario))
				 _scenarios.add(scenario);
		} 
	}

	/**
	 * Clear loaded scenarios.
	 */
	public void flush()
	{
		 _scenarios.clear();
	}
	
	/**
	 * Asynchrone scenario loading.
	 *
	 * @param XML file
	 * @throws JDOMException
	 * @throws IOException
	 * @throws XmlParsingException
	 * @throws UnregisteredOperatorException
	 * @throws Exception
	 */
	public void beginLoad (String xmlFile) throws JDOMException, IOException, XmlParsingException, UnregisteredOperatorException, Exception
	{
		Callback<List<Scenario>> callback = new Callback<List<Scenario>>() {
			
			@Override
			public List<Scenario> callback(Object sender, List<Scenario> product) {
				_scenarios = product;
				return null;
			}
		};
		
		new ScenarioBuilder(xmlFile).build(callback);
	}
	
	/**
	 * Serialize an XMLElement
	 *
	 * @param XML element
	 * @return DOM Element
	 * @throws SerializationException
	 */
	public Element serialize (XmlSerializable element) throws SerializationException
	{
		return new Serializer<XmlSerializable>()
				.handleElement(element);
	}

}
